package com.tn.openrpc.channel
{
	import com.tn.openrpc.client.IStompClient;
	import com.tn.openrpc.stomp.StompTemplate;
	import com.tn.openrpc.util.StompIdUtil;
	import com.tn.requestQueue.IRequestQueue;
	import com.tn.requestQueue.impl.RequestQueue;
	import mx.rpc.AsyncToken;

	/**
	 * An implementation of <code>RemoteChannel</code> that uses <i>Stomp</i>.  The <code>Destination</code>s used by this
	 * <code>StompRemoteChannel</code> should be for its exclusive use.  Any messages received on the <i>response</i>
	 * <code>Destination</code> that do not correlate with a <i>request</i> will cause an exception.
	 */
	public class StompRemoteChannel implements IRemoteChannel
	{

		/*============================================================================*/
		/* Private Properties                                                         */
		/*============================================================================*/

		private var queue:IRequestQueue;

		private var requestDestination:String;

		private var responseDestination:String;

		private var stompClient:IStompClient;

		/*============================================================================*/
		/* Constructor                                                                */
		/*============================================================================*/

		public function StompRemoteChannel(
			stompClient:IStompClient,
			requestDestination:String,
			responseDestination:String
			)
		{
			this.stompClient = stompClient;
			this.requestDestination = requestDestination;
			this.responseDestination = responseDestination;
		}


		/*============================================================================*/
		/* Public Functions                                                           */
		/*============================================================================*/

		public function send(remoteChannelRequest:RemoteChannelRequest):AsyncToken
		{
			var stompRequest:StompTemplate = createSendRequest();
			queueRequest(function():AsyncToken
			{
				return stompRequest.send(remoteChannelRequest);
			});
			return stompRequest.token;
		}

		/*============================================================================*/
		/* Protected Functions                                                        */
		/*============================================================================*/

		protected function createSendRequest():StompTemplate
		{
			return new StompTemplate(
				stompClient,
				requestDestination,
				responseDestination,
				StompIdUtil.generateCorrelationId()
				);
		}

		/*============================================================================*/
		/* Internal Functions                                                         */
		/*============================================================================*/

		internal function queueRequest(item:Function):void
		{
			queue ||= new RequestQueue();
			queue.addRequest(item);
		}
	}
}
